//+------------------------------------------------------------------+
//|                                               MoneyFixedRisk.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert/ExpertMoney.h>       // 专家顾问资金管理基类（提供账户、品种等基础能力）

// wizard description start（MQL5 向导描述，用于策略生成器识别类信息）
//+------------------------------------------------------------------+
//| 类功能描述                                                       |
//| Title=固定风险比例交易                                           |
//| Type=Money                                                       |
//| Name=FixRisk                                                     |
//| Class=CMoneyFixedRisk                                            |
//| Page=                                                            |
//| Parameter=Percent,double,10.0,风险百分比（每笔交易允许亏损的账户资金占比）|
//+------------------------------------------------------------------+
// wizard description end

//+------------------------------------------------------------------+
//| CMoneyFixedRisk 类：固定风险比例资金管理实现                       |
//| 核心能力：继承自 CExpertMoney，根据“每笔交易允许亏损的账户资金固定比例”  |
//|           计算开仓手数，结合止损价格动态调整手数，严格控制单笔交易风险   |
//| 核心逻辑：手数 = (账户余额 × 风险比例) / (每手止损亏损金额)，确保亏损不超预设比例 |
//| 适用场景：追求风险标准化的交易策略（如每笔交易最多亏损账户的1%-5%），    |
//|           适合趋势交易、波段交易等需要设置明确止损的策略               |
//+------------------------------------------------------------------+
class CMoneyFixedRisk : public CExpertMoney
  {
public:
   //----------------------------------------------------------------
   // 构造与析构函数
   //----------------------------------------------------------------
   /**
    * @brief 构造函数：初始化固定风险比例资金管理对象
    * @details 继承父类 CExpertMoney 的初始化逻辑，自动关联账户（m_account）和交易品种（m_symbol）
    */
                     CMoneyFixedRisk(void);

   /**
    * @brief 析构函数：清理固定风险比例资金管理对象
    * @details 释放资源，依赖父类析构逻辑完成账户、品种等对象的清理
    */
                    ~CMoneyFixedRisk(void);

   //----------------------------------------------------------------
   // 开仓手数计算：核心方法，根据固定风险比例和止损计算多空单手数
   //----------------------------------------------------------------
   /**
    * @brief 计算多单（买入）的最大允许开仓手数
    * @param price [in] 计划开仓价格（若为 0，自动使用当前市场卖价 m_symbol.Ask()）
    * @param sl [in] 止损价格（必须设置，否则按品种最小手数开仓）
    * @return double - 最终多单开仓手数（已适配品种的最小/最大手数及手数步长）
    * @note 计算逻辑：
    *       1. 若未设置止损（sl=0），直接返回品种最小手数（m_symbol.LotsMin()）；
    *       2. 计算1标准手（1.0手）在当前开仓价和止损价下的亏损金额；
    *       3. 根据“账户余额 × 风险比例”计算单笔交易允许的最大亏损金额；
    *       4. 用允许亏损金额除以每手亏损金额，得到理论手数，再按品种手数步长取整；
    *       5. 最终手数限制在品种的最小（LotsMin）和最大（LotsMax）手数之间。
    */
   virtual double    CheckOpenLong(double price,double sl);

   /**
    * @brief 计算空单（卖出）的最大允许开仓手数
    * @param price [in] 计划开仓价格（若为 0，自动使用当前市场买价 m_symbol.Bid()）
    * @param sl [in] 止损价格（必须设置，否则按品种最小手数开仓）
    * @return double - 最终空单开仓手数（已适配品种的最小/最大手数及手数步长）
    * @note 计算逻辑与多单一致，仅交易方向（ORDER_TYPE_SELL）和市场价格（Bid 价）不同
    */
   virtual double    CheckOpenShort(double price,double sl);

   //----------------------------------------------------------------
   // 平仓手数计算：虚方法，本类暂不实现（默认返回 0.0，子类可重写）
   //----------------------------------------------------------------
   /**
    * @brief 计算平仓手数（本类专注于开仓风险控制，平仓逻辑由策略自行实现）
    * @param position [in] 持仓信息对象（包含持仓手数、开仓价等信息）
    * @return double - 平仓手数（默认返回 0.0，表示不限制平仓手数）
    * @note 若需自定义平仓逻辑（如部分平仓、盈利达标平仓等），可在子类中重写此方法
    */
   virtual double    CheckClose(CPositionInfo *position);
  };
//+------------------------------------------------------------------+